
package com.scs.application.modules.cert.controller;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.scs.application.core.exceptions.ExportException;
import com.scs.application.core.exceptions.ImportException;
import com.scs.application.core.model.CommonResult;
import com.scs.application.core.model.ImportResult;
import com.scs.application.core.model.PageResult;
import com.scs.application.core.model.RestResult;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.mvc.controller.ImAndExAbleController;
import com.scs.application.core.utils.BeanValidators;
import com.scs.application.core.utils.PoiUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.base.entity.HospitalSupplier;
import com.scs.application.modules.cert.dto.ExcelCertDTO;
import com.scs.application.modules.cert.dto.NoticeUpgradeCertDTO;
import com.scs.application.modules.cert.dto.NoticeUploadCertDTO;
import com.scs.application.modules.cert.entity.Certificate;
import com.scs.application.modules.cert.entity.CertificateHospitalBusiness;
import com.scs.application.modules.cert.entity.CertificateRepository;
import com.scs.application.modules.cert.mapper.CertificateRepositoryMapper;
import com.scs.application.modules.cert.request.CertificateRepositoryQueryRequest;
import com.scs.application.modules.cert.service.CertificateHospitalBusinessService;
import com.scs.application.modules.cert.service.CertificateRepositoryService;
import com.scs.application.modules.cert.service.CertificateService;
import com.scs.application.modules.design.service.QueryGenerator;
import com.scs.application.modules.ext.entity.CertHosup;
import lombok.AllArgsConstructor;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 供应商资质仓库 controller
 */
@AllArgsConstructor
@RestController
@RequestMapping("/cert/certificate_repositorys")
public class CertificateRepositoryController extends CrudController<CertificateRepository, String, CertificateRepositoryService> implements ImAndExAbleController<CertificateRepositoryQueryRequest> {
    private CertificateRepositoryMapper certificateRepositoryMapper;
    private CertificateService certificateService;
    private CertificateHospitalBusinessService certificateHospitalBusinessService;

    @GetMapping("/page")
    public PageResult page(CertificateRepositoryQueryRequest request) {
        IPage page = service.page(request);
        return PageResult.ok("查询成功", page.getRecords(), page.getTotal());
    }

    @GetMapping("/list")
    public CommonResult list(CertificateRepositoryQueryRequest request) {
        List<CertificateRepository> list = service.list(request);
        return CommonResult.ok("查询成功", list);
    }

    /**
     * 添加供应商资质
     *
     * @param entity
     * @return
     */
    @PostMapping("/save_for_supplier")
    public CommonResult saveForSupplier(@RequestBody @Valid CertificateRepository entity) {
        if (entity.getDocIds().size() == 0) {
            return CommonResult.error("资质文件至少上传一个");
        }
        boolean bSave = service.saveForSupplier(entity);
        return bSave ? CommonResult.ok("保存成功", entity) : CommonResult.error("保存失败");
    }

    /**
     * 添加品名资质
     *
     * @param entity
     * @return
     */
    @PostMapping("/save_for_material")
    public CommonResult saveForMaterial(@RequestBody @Valid CertificateRepository entity) {
        if (entity.getDocIds().size() == 0) {
            return CommonResult.error("资质文件至少上传一个");
        }
        boolean bSave = service.saveForMaterial(entity);
        return bSave ? CommonResult.ok("保存成功", entity) : CommonResult.error("保存失败");
    }

    /**
     * 添加厂商资质
     *
     * @param entity
     * @return
     */
    @PostMapping("/save_for_manufacturer")
    public CommonResult saveForManufacturer(@RequestBody @Valid CertificateRepository entity) {
        if (entity.getDocIds().size() == 0) {
            return CommonResult.error("资质文件至少上传一个");
        }
        boolean bSave = service.saveForManufacturer(entity);
        return bSave ? CommonResult.ok("保存成功", entity) : CommonResult.error("保存失败");
    }

    /**
     * 添加品类资质
     *
     * @param entity
     * @return
     */
    @PostMapping("/save_for_catalog")
    public CommonResult saveForCatalog(@RequestBody @Valid CertificateRepository entity) {
        if (entity.getDocIds().size() == 0) {
            return CommonResult.error("资质文件至少上传一个");
        }
        boolean bSave = service.saveForCatalog(entity);
        return bSave ? CommonResult.ok("保存成功", entity) : CommonResult.error("保存失败");
    }

    @PutMapping("/batch_save")
    public CommonResult batchSave(@RequestBody @Valid List<CertificateRepository> children) {
        Assert.notEmpty(children, "至少有一条");
        BeanValidators.validateListWithException(validator, children);

        boolean bSuccess = service.saveOrUpdateBatch(children);
        return bSuccess ? CommonResult.ok("保存成功") : CommonResult.error("保存失败");
    }

    /**
     * 获取供应商资质
     *
     * @param request
     * @return
     */
    @GetMapping("/page_for_supplier")
    public PageResult pageForSupplier(CertificateRepositoryQueryRequest request) {
        IPage page = service.pageForSupplier(request);
        return PageResult.ok("查询成功", page.getRecords(), page.getTotal());
    }


    /**
     * 供应商资质效期预警
     *
     * @param request
     * @return
     */
    @GetMapping("/page_for_supplier_warning")
    public PageResult pageForSupplierWarning(CertificateRepositoryQueryRequest request) {
        IPage page = service.pageForSupplierWarning(request);
        return PageResult.ok("查询成功", page.getRecords(), page.getTotal());
    }

    /**
     * 医院资质效期预警
     *
     * @param request
     * @return
     */
    @GetMapping("/page_for_hospital_warning")
    public PageResult pageForHospitalWarning(CertificateRepositoryQueryRequest request) {
        IPage page = service.pageForHospitalWarning(request);
        return PageResult.ok("查询成功", page.getRecords(), page.getTotal());
    }

    /**
     * 关闭资质 关闭状态修改为 已关闭1
     *
     * @param id
     * @return
     */
    @PostMapping("/close/{id}")
    public CommonResult close(@PathVariable("id") String id) {
        service.close(id);
        return CommonResult.ok("关闭成功");
    }

    /**
     * 升级资质
     *
     * @param entity
     * @return
     */
    @PostMapping("/upgrade")
    public CommonResult upgrade(@RequestBody @Valid CertificateRepository entity) {
        service.upgrade(entity);
        return CommonResult.ok("升级成功");
    }

    /**
     * 院方提醒升级资质
     *
     * @param dto
     * @return
     */
    @PostMapping("/notice_upgrade")
    public CommonResult noticeUpgrade(@RequestBody NoticeUpgradeCertDTO dto) {
        service.noticeUpgrade(dto);
        return CommonResult.ok("提醒成功");
    }


    /**
     * 提醒上传资质
     *
     * @param dto
     * @return
     */
    @PostMapping("/notice_upload")
    public CommonResult noticeUpload(@RequestBody NoticeUploadCertDTO dto) {
        service.noticeUpload(dto);
        return CommonResult.ok("提醒成功");
    }

    /**
     * 供方资格审核，查看资质页
     *
     * @param request
     * @return
     */
    @GetMapping("/list_for_audit")
    public CommonResult listForAudit(CertificateRepositoryQueryRequest request) {
        List<CertificateRepository> list = service.pageForAudit(request);
        return CommonResult.ok("查询成功", list);
    }

    /**
     * 资质提交，修改状态为已提交
     *
     * @param id
     * @return
     */
    @PostMapping("certificate_submit/{id}")
    public CommonResult certificateSubmit(@PathVariable("id") String id) {
        service.certificateSubmit(id);
        return CommonResult.ok("提交成功");
    }

    /**
     * 修正资质信息
     *
     * @param hospitalId
     * @return
     */
    @PostMapping("correction_cert/{hospitalId}")
    public CommonResult correctionCert(@PathVariable("hospitalId") String hospitalId) {
        service.correctionCert(hospitalId);
        return CommonResult.ok("修正任务提交成功");
    }

    @Override
    public void excelTemplate(CertificateRepositoryQueryRequest request) {
        String fileName = "7供应商资质导入.xlsx";
        ExportParams params = PoiUtils.getDefaultExportParams("供应商资质导入模板", "供应商资质信息", true);
        params.setExclusions(new String[]{"错误行号", "错误信息"});
        ExcelCertDTO mockData = PoiUtils.mockData(ExcelCertDTO.class);
        try {
            setDownloadParam(fileName);
            PoiUtils.exportExcel(response().getOutputStream(), params, ExcelCertDTO.class, Lists.newArrayList(mockData));
        } catch (IOException e) {
            throw new ExportException("导出异常", e);
        }
    }

    @Override
    public CommonResult<ImportResult> excelImport(MultipartFile file) throws ImportException {
        return CommonResult.ok("导入成功", service.excelImport(file));
    }

    /***
     * @param request
     * @date: 2024/6/21
     * @Description:  资质预警分页查询
     */
    @GetMapping("/pageWarn")
    public PageResult pageWarn(HttpServletRequest request,@RequestParam Map<String, String> reqData) {
        IPage<CertHosup> page = new Page();
        QueryWrapper<CertificateRepository> queryWrapper = QueryGenerator.initQueryWrapper(request);
        Map<String, Object> userParam = null;
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }

        if (!UserUtils.isAdmin()) {
            // 筛选当前供应商的
            if (UserUtils.isSupplier()) {
                queryWrapper.eq("supplier_id", UserUtils.getSupplierId());
            }
            // 医院角色
            if (UserUtils.isHospital()) {
                // 只筛选当前医院有供货关系的
                List<HospitalSupplier> spList = hospitalSupplierService.list(Wrappers.<HospitalSupplier>query().eq("hospital_id", UserUtils.getHospitalId()));
                if (!spList.isEmpty()) {
                    queryWrapper.in("supplier_id", spList.stream().map(HospitalSupplier::getSupplierId).distinct().collect(Collectors.toList()));
                }else {
                    queryWrapper.eq("1","0");
                }

                // 只筛选该医院定义的资质，如果存在的话
                List<CertificateHospitalBusiness> certificateHospitalBusinessList = certificateHospitalBusinessService
                        .list(Wrappers.<CertificateHospitalBusiness>query()
                                .eq("hospital_id",UserUtils.getHospitalId()));
                if (!certificateHospitalBusinessList.isEmpty()) {
                    queryWrapper.in(
                            "certificate_id",
                            certificateHospitalBusinessList.stream().map(CertificateHospitalBusiness::getCertificateId).collect(Collectors.toList())
                    );
                }
            }
        }
        IPage pageResult = certificateRepositoryMapper.pageWarn(page, queryWrapper, null, userParam);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    @GetMapping("/getByIdForWarn/{id}")
    public CommonResult<CertificateRepository> getByIdForWarn(@PathVariable("id") String id) {
        CertificateRepository result = certificateRepositoryMapper.getByIdForWarn(id);
        fillData(result);
        return CommonResult.ok(result != null ? "查询成功" : "查询失败", result);
    }

    private void fillData(CertificateRepository result) {
        if (result == null || StringUtils.isBlank(result.getCertificateId())) {
            return;
        }
        Certificate certificate  = certificateService.getById(result.getCertificateId());
        if (certificate != null) {
            result.setNeedExpiryDate(certificate.getNeedExpiryDate()).setNeedCertificateNo(certificate.getNeedExpiryDate());
        }
    }

    /***
     * @param entity
     * @Description:  通用保存、更新
     */
    @PostMapping("/saveOrUpdateCommon")
    @Override
    public RestResult saveOrUpdateCommon(@Valid @RequestBody CertificateRepository entity) {
        // 提交升级
        if ("upgrade".equals(entity.getOpType())) {
            entity.setSubmitFlag(CertificateRepository.SUBMIT_FLAG_SUBMITED).setOpType(null);
            service.upgradeCert(entity);
            return RestResult.ok("操作成功", entity);
        }
        if (entity.getDocIds() == null) {
            entity.setDocIds(new JSONArray());
        }
        boolean isOk = service.saveOrUpdate(entity);
        if (!isOk) {
            return RestResult.error("操作失败");
        }
        fillData(entity);
        return RestResult.ok("操作成功", entity);
    }
}
